home *** CD-ROM | disk | FTP | other *** search
/ Aminet 2 / Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso / Aminet / dev / lang / BCPL4Amiga.lha / tripos / mynewcli.c < prev    next >
C/C++ Source or Header  |  1988-12-06  |  9KB  |  280 lines

  1. /* Mynewcli.c - a C language replacement for NEWCLI
  2. Compile and link with Manx 3.4:
  3.   cc mynewcli
  4.   ln mynewcli.o bcpllib.o -lc
  5. By Bill Kinnersley - Dec 18, 1987
  6. Mail:   Physics Dept.
  7.         Montana State University
  8.         Bozeman, MT 59717
  9. BITNET: iphwk@mtsunix1
  10. INTERNET: iphwk%mtsunix1.bitnet@cunyvm.cuny.edu
  11. UUCP: ...psuvax1!mtsunix1.bitnet!iphwk
  12. */
  13.  
  14. #include <stdio.h>
  15. #include <libraries/dosextens.h>
  16. #include <functions.h>
  17. #include <exec/memory.h>
  18. #include "BCPL.h"
  19.  
  20. long *gv;
  21. struct rsdnt {
  22.         BPTR    next;
  23.         long    count;
  24.         BPTR    seg;
  25.         char    length;
  26.         char    name[1];
  27. };
  28.  
  29. struct pathlist {
  30.         BPTR next;
  31.         BPTR lock;
  32. };
  33.  
  34. long cli_init();
  35. struct pathlist *copypath();
  36.  
  37. main(argc, argv) char *argv[]; {
  38.         struct RootNode *root;
  39.         struct DosLibrary *doslib;
  40.         struct DosInfo *dosinfo;
  41.         struct rsdnt *list;
  42.         struct pathlist *sub;
  43.         struct MsgPort *fst;
  44.         struct Process *myproc, *newproc;
  45.         struct CommandLineInterface *cli;
  46.         struct DosPacket *pkt;
  47.         struct FileLock *lock;
  48.         long clitask, *tskarr, taskno;
  49.         long stsz, sz, *oldseglist, *newseglist, res;
  50.         BPTR cd=0, procname=0;
  51.         char *wdwname;
  52.         short i, len;
  53.  
  54.         BCPLInit();
  55.         myproc = (struct Process *)FindTask(0L);
  56.         stsz = myproc->pr_StackSize;
  57.         cli = (struct CommandLineInterface *)BADDR(myproc->pr_CLI);
  58.         gv = (long *)myproc->pr_GlobVec;
  59.  
  60.         oldseglist = (long *)BADDR(myproc->pr_SegList);
  61.         newseglist = (long *)AllocMem(24L, MEMF_CLEAR);
  62.         *newseglist = 24;
  63.         newseglist++;
  64.         for (i=0; i<4; i++) newseglist[i] = oldseglist[i];
  65.  
  66.         doslib = (struct DosLibrary *)OpenLibrary("dos.library", 0L);
  67.         root = (struct RootNode *)doslib->dl_Root;
  68.         tskarr = (long *)BADDR(root->rn_TaskArray);
  69.         dosinfo = (struct DosInfo *)BADDR(root->rn_Info);
  70.  
  71.         for (list = (struct rsdnt *)BADDR(dosinfo->di_NetHand);
  72.                 list; list = (struct rsdnt *)BADDR(list->next))
  73.                 if (strcmp("CLI", list->name)==0) {
  74.                         newseglist[4] = list->seg;
  75.                         if (list->count != -1) list->count++;
  76.                         break;
  77.                 }
  78.  
  79.         wdwname = (argc>1) ? argv[1] : "CON:0/0/640/100/MyNewCLI";
  80.  
  81.         Forbid();
  82.         sz = tskarr[0];
  83.         for (taskno=1; taskno<=sz; taskno++) if (!tskarr[taskno]) break;
  84.         if (taskno>sz) {
  85.                 Permit();
  86.                 FreeMem(--newseglist, 24L);
  87.                 printf("Too many tasks\n");
  88.                 goto failure;
  89.         }
  90.         stsz = 3000;
  91.         procname = MakeBSTR("MyNewCLI");
  92.         if (!(clitask = BCPL(CREATEPROCB, bptr(newseglist), stsz>>2, 0L,
  93.                 procname, bptr(gv)))) {
  94.                 Permit();
  95.                 FreeMem(--newseglist, 24L);
  96.                 printf("Unable to create new process\n");
  97.                 goto failure;
  98.         }
  99.         tskarr[taskno] = (long)clitask;
  100.         newproc =(struct Process *)((long)clitask-(long)sizeof(struct Task));
  101.         newproc->pr_TaskNum = taskno;
  102.         Permit();
  103.  
  104.         cd = DupLock(myproc->pr_CurrentDir);
  105.  
  106.         if (sub = copypath(cli->cli_CommandDir)) {
  107.                 lock = (struct FileLock *)BADDR(sub->lock);
  108.                 fst = lock->fl_Task;
  109.         }
  110.         else fst = (struct MsgPort *)myproc->pr_FileSystemTask;
  111.  
  112.         if (BCPL(SENDPKT, 0L, clitask, cli_init, -1L, 0L, cd,
  113.                 wdwname, bptr(sub), bptr(cli), fst))
  114.                 {FreeBSTR(procname); BCPLQuit(); exit(0);}
  115.  
  116.         printf("Unable to Open Window\n");
  117. failure:
  118.         printf("MyNewCLI Failed\n");
  119.         if (cd) UnLock(cd);
  120.         if (taskno) tskarr[taskno] = 0;
  121.         if (list) if (list->count != -1) list->count--;
  122.         if (procname) FreeBSTR(procname);
  123.         BCPLQuit();
  124.         exit(20);
  125. }
  126.  
  127. struct pathlist *copypath(arg) BPTR arg; {
  128. /* The PATH is stored in cli_CommandDir as a linked list of Locks */
  129. /* Each newly created CLI must inherit the PATH of its creator */
  130.         struct pathlist *oldlist, *newlist, *link, *lastlink;
  131.         long *mem;
  132.  
  133.         newlist = NULL;
  134.         lastlink = (struct pathlist *)&newlist;
  135.         oldlist = (struct pathlist *)BADDR(arg);
  136.         while (oldlist) {
  137.                 if (!(mem = (long *)AllocMem(12L, 1L))) break;
  138.                 mem[0] = 12L;
  139.                 link = (struct pathlist *)&mem[1];
  140.                 link->next = NULL;
  141.                 link->lock = DupLock(oldlist->lock);
  142.                 lastlink->next = bptr(link);
  143.                 lastlink = link;
  144.                 oldlist = (struct pathlist *)BADDR(oldlist->next);
  145.         }
  146.         return (struct pathlist *)(BADDR(newlist));
  147. }
  148.  
  149. struct clistartup {
  150.         long notused[5];
  151.         BPTR curdir, window, path, oldCLI;
  152.         APTR FSTask;
  153. };
  154.  
  155. extern long a0[3];
  156. long retval;
  157. long cli_init(arg) BPTR arg; {
  158.         struct clistartup *pkt; /* this MUST be the first local */
  159.         struct Process *mytask;
  160.         struct CommandLineInterface *oldcli, *mycli;
  161.         struct FileHandle *fh;
  162.         BPTR input, output;
  163.         long saveres, *array, max, i, putpkt, remtask;
  164.         char *bstr, *prompt, *newprompt, *curdir, *newcurdir;
  165.  
  166. #asm
  167.         movem.l a1/a3,-(a7)
  168.         asl.l   #2,d1
  169.         move.l  d1,-4(a5)       ;this initializes pkt */
  170. #endasm
  171.         geta4();
  172.         remtask = gv[34];
  173.         putpkt = gv[42];
  174.  
  175.         oldcli = (struct CommandLineInterface *)BADDR(pkt->oldCLI);
  176.         prompt = (char *)BADDR(oldcli->cli_Prompt);
  177.         curdir = (char *)BADDR(oldcli->cli_SetName);
  178.  
  179.         mytask = (struct Process *)FindTask(0L);
  180.         mycli = (struct CommandLineInterface *)BADDR(mytask->pr_CLI);
  181.         newprompt = (char *)BADDR(mycli->cli_Prompt);
  182.         newcurdir = (char *)BADDR(mycli->cli_SetName);
  183.         mytask->pr_CurrentDir = pkt->curdir;
  184.         mytask->pr_FileSystemTask = pkt->FSTask;
  185.         mytask->pr_WindowPtr = 0L;
  186.  
  187.         if (!(input = Open(pkt->window, MODE_OLDFILE))) {
  188.                 saveres = mytask->pr_Result2;
  189.                 returnpkt(pkt, 0L, saveres);
  190.                 mytask->pr_Result2 = saveres;
  191.                 retval = remtask;
  192.                 goto ret;
  193.         }
  194.         if (!IsInteractive(input)) {
  195.                 Close(input);
  196.                 mytask->pr_Result2 = 206;
  197.                 input = 0L;
  198.         }
  199.         mycli->cli_StandardInput = input;
  200.         mytask->pr_CIS = input;
  201.  
  202.         fh = (struct FileHandle *)BADDR(input);
  203.         mytask->pr_ConsoleTask = (APTR)fh->fh_Type;
  204.  
  205.         if (!(output = Open("*", MODE_NEWFILE))) {
  206.                 Close(input);
  207.                 saveres = mytask->pr_Result2;
  208.                 returnpkt(pkt, 0L, saveres);
  209.                 mytask->pr_Result2 = saveres;
  210.                 retval = remtask;
  211.                 goto ret;
  212.         }
  213.         mycli->cli_StandardOutput = output;
  214.         mytask->pr_COS = output;
  215.         mycli->cli_CurrentInput = mycli->cli_StandardInput;
  216.         mycli->cli_CurrentOutput = mycli->cli_StandardOutput;
  217.         mycli->cli_Background = 0;
  218.         mycli->cli_CommandDir = pkt->path;
  219.         mycli->cli_ReturnCode = 0;
  220.         mycli->cli_FailLevel = oldcli->cli_FailLevel;
  221.         mycli->cli_Result2 = 0;
  222.         bstr = (char *)BADDR(mycli->cli_CommandFile);
  223.         bstr[0] = 0;
  224.         mycli->cli_DefaultStack = oldcli->cli_DefaultStack;
  225.         mycli->cli_Module = 0;
  226.  
  227.         max = prompt[0];
  228.         for (i=0; i<=max; i++) newprompt[i] = prompt[i];
  229.  
  230.         max = curdir[0];
  231.         for (i=0; i<=max; i++) newcurdir[i] = curdir[i];
  232.  
  233.         printf("New CLI Task %ld\n", mytask->pr_TaskNum);
  234.         array = (long *)BADDR(mytask->pr_SegList);
  235.         array[3] = 0;
  236.         mytask->pr_Result2 = bptr(pkt);
  237.         retval = putpkt;
  238. /* After we return, the new CLI will call retval with argument pr_Result2 */
  239. ret:    ;
  240. #asm
  241.         dseg
  242.         public  _a0
  243.         cseg
  244.         lea     _retval,a1
  245.         move.l  (a1),d1
  246.         lea     _a0,a0
  247.         move.l  0(a0),a2
  248.         move.l  8(a0),a6
  249.         suba.l  a0,a0
  250.         movem.l (a7)+,a1/a3
  251.         unlk    a5
  252.         jmp     (a6)
  253. #endasm
  254. }
  255.  
  256. returnpkt(pkt, res1, res2) struct DosPacket *pkt; long res1, res2; {
  257.         struct Message *msg;
  258.         struct MsgPort *port;
  259.  
  260.         port = pkt->dp_Port;
  261.         msg = pkt->dp_Link;
  262.         msg->mn_Node.ln_Name = (char *)pkt;
  263.         msg->mn_Node.ln_Succ = msg->mn_Node.ln_Pred = 0L;
  264.         pkt->dp_Res1 = res1;
  265.         pkt->dp_Res2 = res2;
  266.         PutMsg(port, msg);
  267. }
  268.  
  269. /*struct DosPacket *taskwait() {
  270.         struct Process *mytask;
  271.         struct MsgPort *myport;
  272.         struct Message *msg;
  273.  
  274.         mytask = (struct Process *)FindTask(0L);
  275.         myport = &mytask->pr_MsgPort;
  276.         WaitPort(myport);
  277.         msg = GetMsg(myport);
  278.         return((struct DosPacket *)msg->mn_Node.ln_Name);
  279. }*/
  280.